package com.dhz.common.base.vo;

import com.dhz.common.base.domain.PageQuery;

import java.util.List;

/**
 * 分页容器
 * @param <T> {Bean}
 */
public class PageVO<T> implements BaseVO {

    /** 当前页码 */
    private int pageNum;
    /** 每页数量 */
    private int pageSize;
    /** 当前页记录数 */
    private int currentSize;
    /** 当前页第一个元素在总体数据中的位置 */
    private int startIndex;
    /** 当前页最后一个元素在总体数据中的位置 */
    private int endIndex;
    /** 总记录数 */
    private long totalRows;
    /** 总页数 */
    private int totalPages;
    /** 当前页数据集合 */
    private List<T> list;
    /** 导航页码个数 */
    private int navPageSize;
    /** 导航页页码集合 */
    private int[] navPageNums;
    /** 第一页页码 */
    private int firstPageNum = 1;
    /** 前一页页码 */
    private int prePageNum;
    /** 后一页页码 */
    private int nextPageNum;
    /** 最后一页页码 */
    private int lastPageNum;

    /** 是否是第一个 */
    private boolean first = false;
    /** 是否是最后一页 */
    private boolean last = false;

    public PageVO(PageQuery query, List<T> list, long count) {
        this.pageNum = query.getPageNum();
        this.pageSize = query.getPageSize();
        this.startIndex = query.getStartIndex();
        this.navPageSize = query.getNavPageSize();
        this.list = list;
        this.currentSize = list.size();
        // 设置总记录数和总页数
        setTotalRows(count);
        // 设置导航页码
        calcNavPageNums();
        // 计算前后页页码
        calcPreNextPageNum();
        first = pageNum==1;
        last = pageNum==totalPages;
    }

    /**
     * 计算生成导航页码
     */
    private void calcNavPageNums() {
        // 当要求显示的到行业吗数大于等于记录总页数时
        if (totalPages <= navPageSize) {
            navPageNums = new int[totalPages];
            for (int i=0; i<totalPages; i++) {
                navPageNums[i] = i+1;
            }
        }
        // 当要求显示的导航页码数小于总页数时
        else {
            navPageNums = new int[navPageSize];
            int startPageNum = pageNum - navPageSize / 2;
            int endPageNum = pageNum + navPageSize / 2;
            if (startPageNum < 1) {
                startPageNum = 1;
                for (int i=0; i<navPageSize; i++) {
                    navPageNums[i] = i+1;
                }
            }
            // 如果导航页码最后一页大于总页数，则将总页数设置为最后一页
            else if (endPageNum > totalPages) {
                endPageNum = totalPages;
                for (int i=navPageSize-1; i>=0; i--) {
                    navPageNums[i] = endPageNum--;
                }
            }
            // 如果导航页中的页码都在中间
            else {
                for (int i=0; i<navPageSize; i++) {
                    navPageNums[i] = startPageNum++;
                }
            }
        }
    }

    /**
     * 计算前后页，第一页，最后一页
     */
    private void calcPreNextPageNum() {
        if (navPageNums != null && navPageNums.length > 0) {
            firstPageNum = navPageNums[0];
            lastPageNum = navPageNums[navPageNums.length - 1];
            if (pageNum > 1) {
                prePageNum = pageNum - 1;
            }
            if (pageNum < totalPages) {
                nextPageNum = pageNum + 1;
            }
        }
    }

    public void setTotalRows(long totalRows) {
        this.totalRows = totalRows;
        // 根据记录数设置总页数, 如果每页数量设置为0，表示不进行分页，取出全部数据只用一页
        this.totalPages = this.pageSize==0?1:(int)Math.ceil((double)this.totalRows / (double)this.getPageSize());
    }

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex(int startIndex) {
        this.startIndex = startIndex;
    }

    public int getEndIndex() {
        return endIndex;
    }

    public void setEndIndex(int endIndex) {
        this.endIndex = endIndex;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }

    public int getFirstPageNum() {
        return firstPageNum;
    }

    public void setFirstPageNum(int firstPageNum) {
        this.firstPageNum = firstPageNum;
    }

    public int getPrePageNum() {
        return prePageNum;
    }

    public void setPrePageNum(int prePageNum) {
        this.prePageNum = prePageNum;
    }

    public int getNextPageNum() {
        return nextPageNum;
    }

    public void setNextPageNum(int nextPageNum) {
        this.nextPageNum = nextPageNum;
    }

    public int getLastPageNum() {
        return lastPageNum;
    }

    public void setLastPageNum(int lastPageNum) {
        this.lastPageNum = lastPageNum;
    }

    public int getCurrentSize() {
        return currentSize;
    }

    public void setCurrentSize(int currentSize) {
        this.currentSize = currentSize;
    }

    public int[] getNavPageNums() {
        return navPageNums;
    }

    public void setNavPageNums(int[] navPageNums) {
        this.navPageNums = navPageNums;
    }

    public int getNavPageSize() {
        return navPageSize;
    }

    public void setNavPageSize(int navPageSize) {
        this.navPageSize = navPageSize;
    }

    public long getTotalRows() {
        return totalRows;
    }

    public boolean isFirst() {
        return first;
    }

    public void setFirst(boolean first) {
        this.first = first;
    }

    public boolean isLast() {
        return last;
    }

    public void setLast(boolean last) {
        this.last = last;
    }
}
